﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using HostTool.Core;
using HostTool.Protocol;
using System.Reflection;
using HostTool.Util;
using System.Threading;

namespace HostTool.GUI
{
    public partial class CPUParam : UserControl
    {
        DSPParam dspParam = new DSPParam();
        Thread threadUpdate;
        public CPUParam()
        {
            InitializeComponent();
        }


        public CPU CPU
        {
            get;
            set;
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (CPU != null)
            {
                ultraLabel1.Text = CPU.Descriptor;
            }
            propertyGrid1.SelectedObject = dspParam;
        }


        private void ProcessParam(Frame frame)
        {
            if (frame != null)
            {
                this.Invoke(new MethodInvoker(delegate
                {

                    int length = frame.RealDataLength;
                    byte[] data = frame.RawData;
                    int offset = frame.RealDataOffset;



                    dspParam.Update(data, offset, length);


                    propertyGrid1.Enabled = true;
                    propertyGrid1.Refresh();
                    

                }));
            }
        }
        /// <summary>
        /// 读取
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ultraButton1_Click(object sender, EventArgs e)
        {
            CPU cpu = this.CPU;
            if (cpu == null) return;
            RequestPackage package = cpu.CreateRequest(0x03, 0x03, 2000);

            package.CallbackHandler = new RequestCallbackHandler(ProcessParam);
            cpu.SendRequest(package);
        }

        /// <summary>
        /// 写入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ultraButton2_Click(object sender, EventArgs e)
        {
            if ((threadUpdate == null) || (threadUpdate.IsAlive == false))
            {
                threadUpdate = new Thread(new ThreadStart(ProcUpdateFirmware));
                threadUpdate.IsBackground = true;
                threadUpdate.Start();
            }
            else
            {
                MessageBox.Show("正在更新中...，请稍候再试！","更新",MessageBoxButtons.OK,MessageBoxIcon.Warning);
            }
        }

        /// <summary>
        /// 更新固件文件
        /// </summary>
        private void ProcUpdateFirmware()
        {

            try {

                CPU cpu = this.CPU;

                byte[] fileData = dspParam.GetParam();

                FirmwareType firmwareType = cpu.FirmwareList[2];

                //计算传输的帧个数
                int frameCnt = fileData.Length / cpu.MTU;
                int leftLength = fileData.Length % cpu.MTU;

                if (leftLength > 0)
                {
                    frameCnt++;
                }
                //计算开始升级帧数据
                byte[] frameTx = new byte[4];
                int maxFrameNum = frameCnt - 1;

                frameTx[0] = 0; //0-软件升级 1-文件下载 
                frameTx[1] = (byte)(maxFrameNum >> 8);
                frameTx[2] = (byte)(maxFrameNum & 0xff);
                frameTx[3] = firmwareType.Type; //软件类型

                byte[] frameData = new byte[2 + cpu.MTU];

                bool resetOK = false;


                RequestPackage package = cpu.CreateRequest(0x02, 0x08, 100);
                for (int i = 0; i < 3; i++)
                {
                    //(1)复位


                    cpu.SendRequest(package);

                    Frame frame = package.WaitResponse();

                    if (frame != null)
                    {

                    }

                    for (int j = 0; j < 4; j++)
                    {
                        Thread.Sleep(1000);

                        this.Invoke(new MethodInvoker(delegate
                        {
                            ultraLabel1.Text = cpu.Descriptor + String.Format("|等待CPU重启({0})秒...", 4 - j);

                        }));

                    }

                    //(2)发送升级命令
                    this.Invoke(new MethodInvoker(delegate
                    {
                        ultraLabel1.Text = cpu.Descriptor + "|发送升级命令";
                    }));
                    package = cpu.CreateRequest(0x03, 0x11, frameTx, frameTx.Length, 5000);
                    cpu.SendRequest(package);
                    frame = package.WaitResponse(); //等待5秒
                    if (frame != null)
                    {
                        int dOffset = frame.RealDataOffset;
                        if (frame.RawData[dOffset] == 0x11)
                        {
                            resetOK = true;
                            break;
                        }
                    }
                }

                if (resetOK == false)
                {
                    this.Invoke(new MethodInvoker(delegate
                    {
                        ultraLabel1.Text = cpu.Descriptor + "|升级失败:CPU复位失败!";

                    }));
                    return;
                }
                //(3)发送固件数据
                int offset = 0;
                for (int i = 0; i < frameCnt; i++)
                {

                    this.Invoke(new MethodInvoker(delegate
                    {
                        ultraLabel1.Text = cpu.Descriptor + String.Format("|发送升级包({0}/{1})", i + 1, frameCnt);
                    }));

                    int txLen = cpu.MTU;
                    if ((i == frameCnt - 1) && (leftLength > 0))
                    {
                        txLen = leftLength;
                    }
                    Array.Copy(fileData, offset, frameData, 2, txLen);
                    offset += txLen;

                    frameData[0] = (byte)(i >> 8); //帧序号
                    frameData[1] = (byte)(i & 0xff);

                    package = cpu.CreateRequest(0x03, 0x12, frameData, txLen + 2, 5000);

                    bool sendOK = false;
                    for (int j = 0; j < 3; j++)
                    {

                        cpu.SendRequest(package);

                        Frame frame = package.WaitResponse();
                        if (frame != null)
                        {
                            int dOffset = frame.RealDataOffset;
                            if (frame.RawData[dOffset] != frameData[0]) continue;
                            if (frame.RawData[dOffset + 1] != frameData[1]) continue;

                            if (frame.RawData[dOffset + 2] != 0) continue;

                            sendOK = true;


                            break;
                        }
                    }

                    if (sendOK == false)
                    {
                        this.Invoke(new MethodInvoker(delegate
                        {
                            ultraLabel1.Text = cpu.Descriptor + "|升级失败:发送升级数据包失败!";

                        }));
                        return;
                    }


                }

                //(4)等待应用程序启动
                bool updateResetOK = false;
                package = cpu.CreateRequest(0x03, 0x14, 2000);
                for (int i = 0; i < 30; i++)
                {


                    cpu.SendRequest(package);

                    this.Invoke(new MethodInvoker(delegate
                    {
                        ultraLabel1.Text = cpu.Descriptor + String.Format("|查询升级状态({0}/{1})...", i + 1, 30);

                    }));

                    Frame frame = package.WaitResponse();

                    if (frame != null)
                    {

                        if (frame.RawData[frame.RealDataOffset] == 0)
                        {
                            updateResetOK = true;

                            this.Invoke(new MethodInvoker(delegate
                            {
                                ultraLabel1.Text = cpu.Descriptor + "|升级成功!";

                            }));
                            break;
                        }
                    }
                    Thread.Sleep(1000);

                }
                if (updateResetOK == false)
                {
                    this.Invoke(new MethodInvoker(delegate
                    {
                        ultraLabel1.Text = cpu.Descriptor + "|升级失败:查询升级状态失败!";

                    }));
                }
            }
            catch (Exception)
            { 
            }

            

        }

    }


    enum ParamMode
    {
        [Description("硬件设置")]
        Hardware,
        [Description("参数设置")]
        Software
    }
    enum LineMode
    {
        [Description("电化线路")]
        ElecLine,
        [Description("非电化线路")]
        NonElecLine,
    }
    enum LightModeYP
    {
        [Description("3060模式")]
        Mode3060,
        [Description("1.9模式")]
        Mode19,
        
    }
    enum LightModeJSJS
    {
        [Description("标准")]
        ModeStandard,
        [Description("哈局")]
        ModeHJ,
    }



    /// <summary>
    /// 枚举转换器
    /// 用此类之前，必须保证在枚举项中定义了Description
    /// </summary>
    public class EnumConverter : ExpandableObjectConverter
    {
        /// <summary>
        /// 枚举项集合
        /// </summary>
        Dictionary<object, string> dic;
        /// <summary>
        /// 构造函数
        /// </summary>
        public EnumConverter()
        {
            dic = new Dictionary<object, string>();
        }

        /// <summary>
        /// 加载枚举项集合
        /// </summary>
        /// <param name="context"></param>
        private void LoadDic(ITypeDescriptorContext context)
        {
            dic = GetEnumValueDesDic(context.PropertyDescriptor.PropertyType);
        }
        /// <summary>
        /// 是否可从来源转换
        /// </summary>
        /// <param name="context"></param>
        /// <param name="sourceType"></param>
        /// <returns></returns>
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string)) return true;
            return base.CanConvertFrom(context, sourceType);
        }

        /// <summary>
        /// 从来源转换
        /// </summary>
        /// <param name="context"></param>
        /// <param name="culture"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is string)
            {
                //如果是枚举
                if (context.PropertyDescriptor.PropertyType.IsEnum)
                {
                    if (dic.Count <= 0)
                        LoadDic(context);

                    foreach (object obj in dic.Keys)
                    {
                        if (dic[obj] == value.ToString())
                        { return obj; }
                    }
                }
            }
            return base.ConvertFrom(context, culture, value);
        }


        /// <summary>
        /// 是否可转换
        /// </summary>
        /// <param name="context"></param>
        /// <param name="destinationType"></param>
        /// <returns></returns>
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return true; }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return true; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return true; }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            if (dic == null || dic.Count <= 0)
                LoadDic(context);
            StandardValuesCollection vals = new TypeConverter.StandardValuesCollection(dic.Keys);
            return vals;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="culture"></param>
        /// <param name="value"></param>
        /// <param name="destinationType"></param>
        /// <returns></returns>
        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if (dic.Count <= 0)
                LoadDic(context);
            foreach (object key in dic.Keys)
            {
                if (key.ToString() == value.ToString() || dic[key] == value.ToString())
                {
                    return dic[key].ToString();
                }
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }


        /// <summary>
        /// 记载枚举的值+描述
        /// </summary>
        /// <param name="enumType"></param>
        /// <returns></returns>
        public Dictionary<object, string> GetEnumValueDesDic(Type enumType)
        {
            Dictionary<object, string> dic = new Dictionary<object, string>();
            FieldInfo[] fieldinfos = enumType.GetFields();
            foreach (FieldInfo field in fieldinfos)
            {
                if (field.FieldType.IsEnum)
                {
                    Object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
                    if (objs.Length > 0)
                    {
                        dic.Add(Enum.Parse(enumType, field.Name), ((DescriptionAttribute)objs[0]).Description);
                    }
                }
            } return dic;
        }
    }



    [TypeConverter(typeof(PropertySorter))]
    class DSPParam
    {
        const string CATEGORY0 = "0-参数方式";
        const string CATEGORY1 = "1-ZPW2000";
        const string CATEGORY2 = "2-国产移频";
        const string CATEGORY3 = "3-交流计数";
        const string CATEGORY4 = "4-单轨条";
        const string CATEGORY5 = "5-极频";
        const string CATEGORY6 = "6-TVM430";
        const string CATEGORY7 = "7-传感器特征码";

        byte[] param = new byte[] { 
        //[PARA方式]
        0xAA,0xAA,//
        //[ZPW2000]
        0x01,0x00,//(2)[ZPW2000] 解码允许
        0x5D,0x00,//(4)[ZPW2000] 通道增益1
        0x5D,0x00,//(6)[ZPW2000] 通道增益2
        0x5D,0x00,//(8)[ZPW2000] 通道增益3
        0x5D,0x00,//(10)[ZPW2000] 通道增益4
        0xAC,0x0D, //(12)[ZPW2000] 掉灯延时
        0x20,0x4E, //(14)[ZPW2000] 载频锁定延时
        //[国产移频]
        0x01,0x00, //(16) [国产移频]解码允许
        0x5D,0x00, //(18) [国产移频]通道增益
        0x5D,0x00, //(20)
        0x5D,0x00, //(22)
        0x5D,0x00, //(24)
        0xAC,0x0D, //(26)
        0x01,0x00,  //(28)
        0x00,0x00, //(30)
        //[交流计数]
        0x01,0x00, //(32)[交流计数] 解码允许
        0x01,0x00,
        0x5C,0x00, //(36)
        0x5C,0x00,
        0x34, 0x21, //(40)
        0x64, 0x19, //(42)
        0x00,0x00, //(44)
        //[单轨条]
        0x00,0x00,  //(46)
        0x64,0x00,  //(48)
        0x74,0x0E,  //(50)
        0x98,0x3A,  //(52)
        //[极频] 
        0x00,0x00,  //(54)
        0x64,0x00,  //(56)
        0x74,0x0E,  //(58)
        //[TVM430]
        0x00,0x00,  //(60)
        0x64,0x00,  //(62)
        0x64,0x00,  //(64)
        0x64,0x00,  //(66)
        0x64,0x00,  //(68)
        0x74,0x0E,  //(70)
        //[传感器特征码]
        0x10,0x27,  //(72)
        0x50,0x00,  //(74)
        0xB8,0x0B,  //(76)
        //[CRC]
        0x81,0x9E,
        };



        public byte[] GetParam()
        {
            byte[] data=new byte[param.Length];
            Array.Copy(param, data, param.Length);

            int len=data.Length-2;
            UInt16 crc = CRC16.ComputeCRC16(data, 0, len);

            data[len] = (byte)((crc >> 8) & 0xff);
            data[len+1] = (byte)(crc & 0xff);
           

            return data;

        }

        public void Update(byte[] data, int offset, int length)
        {
            int min = Math.Min(length, param.Length);

            Array.Copy(data, offset, param, 0, min);
        }

        [CategoryAttribute(CATEGORY0)]
        [DisplayName("参数方式")]
        [DescriptionAttribute("5555H:采用硬件设置 aaaaH:采用参数设置")]
        [PropertyOrder(0)]
        [TypeConverter(typeof(EnumConverter))]
        public ParamMode Mode
        {
            get
            {
                UInt16 mode = BitConverter.ToUInt16(param, 0);
                if (mode == 0xaaaa) return ParamMode.Software;
                return ParamMode.Hardware;
            }
            set
            {
                if (value == ParamMode.Software)
                {
                    param[0] = 0xaa;
                    param[1] = 0xaa;
                }
                else
                {
                    param[0] = 0x55;
                    param[1] = 0x55;
                }
            }
        }


        #region ZPW2000
        [CategoryAttribute(CATEGORY1)]
        [DisplayName("解码允许")]
        [PropertyOrder(1)]
        public bool ZPW2000Allow
        {
            get
            {
                uint val = BitConverter.ToUInt16(param, 2);
                return (val == 1) ? true : false;
            }
            set
            {

                uint val = (uint)(value ? 1 : 0);
                param[2] = (byte)(val & 0xff);
                param[3] = (byte)((val >> 8) & 0xff);
            }
        }

        [CategoryAttribute(CATEGORY1)]
        [DisplayName("通道增益")]
        [DescriptionAttribute("4个通道的增益")]
        [PropertyOrder(2)]
        public string ZPW2000Gain
        {
            get
            {
                uint g1 = BitConverter.ToUInt16(param, 4);
                uint g2 = BitConverter.ToUInt16(param, 6);
                uint g3 = BitConverter.ToUInt16(param, 8);
                uint g4 = BitConverter.ToUInt16(param, 10);
                return g1 + "," + g2 + "," + g3 + "," + g4;
            }
            set
            {
                if (string.IsNullOrEmpty(value)) return;

                string[] g = value.Split(new char[] { ','});
                if (g.Length >= 4)
                {

                    UInt16 g1 = 0;
                    UInt16 g2 = 0;
                    UInt16 g3 = 0;
                    UInt16 g4 = 0;

                    if (UInt16.TryParse(g[0], out g1) && UInt16.TryParse(g[1], out g2) && UInt16.TryParse(g[2], out g3) && UInt16.TryParse(g[3], out g4))
                    {
                        param[4] = (byte)(g1 & 0xff);
                        param[5] = (byte)((g1>>8) & 0xff);
                        param[6] = (byte)(g2 & 0xff);
                        param[7] = (byte)((g2>>8) & 0xff);
                        param[8] = (byte)(g3 & 0xff);
                        param[9] = (byte)((g3>>8) & 0xff);
                        param[10] = (byte)(g4 & 0xff);
                        param[11] = (byte)((g4 >> 8) & 0xff);
                    }
                    

                }


            }
        }
        [CategoryAttribute(CATEGORY1)]
        [DisplayName("掉灯延时")]
        [PropertyOrder(3)]
        public UInt16 ZPW2000DropDelay
        {
            get
            {
                return BitConverter.ToUInt16(param, 12);
            }
            set
            {


                param[12] = (byte)(value & 0xff);
                param[13] = (byte)((value >> 8) & 0xff);
            }
        }

        [CategoryAttribute(CATEGORY1)]
        [DisplayName("载波锁定延时")]
        [PropertyOrder(4)]
        public UInt16 ZPW2000LockDelay
        {
            get
            {
                return BitConverter.ToUInt16(param, 14);
            }
            set
            {


                param[14] = (byte)(value & 0xff);
                param[15] = (byte)((value >> 8) & 0xff);
            }
        }
        #endregion

        #region 国产移频

        [CategoryAttribute(CATEGORY2)]
        [DisplayName("解码允许")]
        [PropertyOrder(5)]
        public bool YPAllow
        {
            get
            {
                uint val = BitConverter.ToUInt16(param, 16);
                return (val == 1) ? true : false;
            }
            set
            {

                uint val = (uint)(value ? 1 : 0);
                param[16] = (byte)(val & 0xff);
                param[17] = (byte)((val >> 8) & 0xff);
            }
        }

        [CategoryAttribute(CATEGORY2)]
        [DisplayName("通道增益")]
        [DescriptionAttribute("4个通道的增益")]
        [PropertyOrder(6)]
        public string YPGain
        {
            get
            {
                uint g1 = BitConverter.ToUInt16(param, 18);
                uint g2 = BitConverter.ToUInt16(param, 20);
                uint g3 = BitConverter.ToUInt16(param, 22);
                uint g4 = BitConverter.ToUInt16(param, 24);
                return g1 + "," + g2 + "," + g3 + "," + g4;
            }
            set
            {
                if (string.IsNullOrEmpty(value)) return;

                string[] g = value.Split(new char[] { ',' });
                if (g.Length >= 4)
                {

                    UInt16 g1 = 0;
                    UInt16 g2 = 0;
                    UInt16 g3 = 0;
                    UInt16 g4 = 0;

                    if (UInt16.TryParse(g[0], out g1) && UInt16.TryParse(g[1], out g2) && UInt16.TryParse(g[2], out g3) && UInt16.TryParse(g[3], out g4))
                    {
                        param[18] = (byte)(g1 & 0xff);
                        param[19] = (byte)((g1 >> 8) & 0xff);
                        param[20] = (byte)(g2 & 0xff);
                        param[21] = (byte)((g2 >> 8) & 0xff);
                        param[22] = (byte)(g3 & 0xff);
                        param[23] = (byte)((g3 >> 8) & 0xff);
                        param[24] = (byte)(g4 & 0xff);
                        param[25] = (byte)((g4 >> 8) & 0xff);
                    }


                }
            }
        }
        [CategoryAttribute(CATEGORY2)]
        [DisplayName("掉灯延时")]
        [PropertyOrder(7)]
        public UInt16 YPDropDelay
        {
            get
            {
                return BitConverter.ToUInt16(param, 26);
            }
            set
            {


                param[26] = (byte)(value & 0xff);
                param[27] = (byte)((value >> 8) & 0xff);
            }
        }

        [CategoryAttribute(CATEGORY2)]
        [DisplayName("线路方式")]
        [DescriptionAttribute("0:电化线路 1:非电化延时")]
        [PropertyOrder(8)]
        [TypeConverter(typeof(EnumConverter))]
        public LineMode YPLineMode
        {
            get
            {
                UInt16 val=BitConverter.ToUInt16(param, 28);
                if (val == 0) return LineMode.ElecLine;
                return LineMode.NonElecLine;
            }
            set
            {
                if (value == LineMode.ElecLine)
                {

                    param[28] = 0;
                    param[29] = 0;
                }
                else
                {
                    param[28] = 1;
                    param[29] = 0;
                }

            }
        }


        [CategoryAttribute(CATEGORY2)]
        [DisplayName("点灯方式")]
        [DescriptionAttribute("0:3060模式 1:1.9模式")]
        [PropertyOrder(9)]
        [TypeConverter(typeof(EnumConverter))]
        public LightModeYP YPLightMode
        {
            get
            {
                UInt16 val=BitConverter.ToUInt16(param, 30);

                if (val == 0) return LightModeYP.Mode3060;
                return LightModeYP.Mode19;
            }
            set
            {
                if (value == LightModeYP.Mode3060)
                {
                    param[30] = 0;
                    param[31] = 0;
                }
                else
                {
                    param[30] = 1;
                    param[31] = 0;
                }

              
            }
        }

        #endregion

        #region 交流计数
        [CategoryAttribute(CATEGORY3)]
        [DisplayName("解码允许")]
        [PropertyOrder(10)]
        public string JLJSAllow
        {
            get
            {
                uint a1 = BitConverter.ToUInt16(param, 32);
                uint a2 = BitConverter.ToUInt16(param, 34);
                return a1 + "," + a2;
            }
            set
            {

                if (string.IsNullOrEmpty(value)) return;

                string[] a = value.Split(new char[] { ',' });
                if (a.Length >= 2)
                {

                    UInt16 a1 = 0;
                    UInt16 a2 = 0;

                    if (UInt16.TryParse(a[0], out a1) && UInt16.TryParse(a[1], out a2))
                    {
                        a1 = (UInt16)(a1 == 0 ? 0 : 1);
                        a2 = (UInt16)(a2 == 0 ? 0 : 1);
                        param[32] = (byte)(a1 & 0xff);
                        param[33] = (byte)((a1 >> 8) & 0xff);
                        param[34] = (byte)(a2 & 0xff);
                        param[35] = (byte)((a2 >> 8) & 0xff);
                    }


                }
            }
        }

        [CategoryAttribute(CATEGORY3)]
        [DisplayName("通道增益")]
        [PropertyOrder(11)]
        public string JLJSGain
        {
            get
            {
                uint g1 = BitConverter.ToUInt16(param, 36);
                uint g2 = BitConverter.ToUInt16(param, 38);
                return g1 + "," + g2;
            }
            set
            {
                if (string.IsNullOrEmpty(value)) return;

                string[] g = value.Split(new char[] { ',' });
                if (g.Length >= 2)
                {

                    UInt16 g1 = 0;
                    UInt16 g2 = 0;

                    if (UInt16.TryParse(g[0], out g1) && UInt16.TryParse(g[1], out g2))
                    {
                        param[36] = (byte)(g1 & 0xff);
                        param[37] = (byte)((g1 >> 8) & 0xff);
                        param[38] = (byte)(g2 & 0xff);
                        param[39] = (byte)((g2 >> 8) & 0xff);
                        
                    }


                }
            }
        }
        [CategoryAttribute(CATEGORY3)]
        [DisplayName("掉灯延时1")]
        [PropertyOrder(12)]
        public UInt16 JLJSDropDelay1
        {
            get
            {
                return BitConverter.ToUInt16(param, 40);
            }
            set
            {


                param[40] = (byte)(value & 0xff);
                param[41] = (byte)((value >> 8) & 0xff);
            }
        }

        [CategoryAttribute(CATEGORY3)]
        [DisplayName("掉灯延时2")]
        [PropertyOrder(13)]
        public UInt16 JLJSDropDelay2
        {
            get
            {
                return BitConverter.ToUInt16(param, 42);
            }
            set
            {


                param[42] = (byte)(value & 0xff);
                param[43] = (byte)((value >> 8) & 0xff);
            }
        }
        [CategoryAttribute(CATEGORY3)]
        [DisplayName("点灯方式")]
        [PropertyOrder(14)]
        [TypeConverter(typeof(EnumConverter))]
        public LightModeJSJS JLJSLightMode
        {
            get
            {
                UInt16 val=BitConverter.ToUInt16(param, 44);
                if (val == 0) return LightModeJSJS.ModeStandard;
                return LightModeJSJS.ModeHJ;
            }
            set
            {

                if (value == LightModeJSJS.ModeStandard)
                {
                    param[44] = 0;
                    param[45] = 0;
                }
                else
                {
                    param[44] = 1;
                    param[45] = 0;
                }
                
            }
        }
        #endregion

        #region 单轨条
        [CategoryAttribute(CATEGORY4)]
        [DisplayName("解码允许")]
        [PropertyOrder(15)]
        public bool OneTrackAllow
        {
            get
            {
                uint val = BitConverter.ToUInt16(param, 46);
                return (val == 1) ? true : false;
            }
            set
            {

                uint val = (uint)(value ? 1 : 0);
                param[46] = (byte)(val & 0xff);
                param[47] = (byte)((val >> 8) & 0xff);
            }
        }

        [CategoryAttribute(CATEGORY4)]
        [DisplayName("通道增益")]
        [PropertyOrder(16)]
        public UInt16 OneTrackGain
        {
            get
            {
                UInt16 g1 = BitConverter.ToUInt16(param, 48);
                return g1;
            }
            set
            {
                param[48] = (byte)(value & 0xff);
                param[49] = (byte)((value>>8) & 0xff);
            }
        }
        [CategoryAttribute(CATEGORY4)]
        [DisplayName("掉灯延时")]
        [PropertyOrder(17)]
        public UInt16 OneTrackDropDelay
        {
            get
            {
                return BitConverter.ToUInt16(param, 50);
            }
            set
            {


                param[50] = (byte)(value & 0xff);
                param[51] = (byte)((value >> 8) & 0xff);
            }
        }

        [CategoryAttribute(CATEGORY4)]
        [DisplayName("载波锁定延时")]
        [PropertyOrder(18)]
        public UInt16 OneTrackLockDelay
        {
            get
            {
                return BitConverter.ToUInt16(param, 52);
            }
            set
            {


                param[52] = (byte)(value & 0xff);
                param[53] = (byte)((value >> 8) & 0xff);
            }
        }
        #endregion

        #region 极频
        [CategoryAttribute(CATEGORY5)]
        [DisplayName("解码允许")]
        [PropertyOrder(19)]
        public bool JPAllow
        {
            get
            {
                uint val = BitConverter.ToUInt16(param, 54);
                return (val == 1) ? true : false;
            }
            set
            {

                uint val = (uint)(value ? 1 : 0);
                param[54] = (byte)(val & 0xff);
                param[55] = (byte)((val >> 8) & 0xff);
            }
        }

        [CategoryAttribute(CATEGORY5)]
        [DisplayName("通道增益")]
        [PropertyOrder(20)]
        public UInt16 JPGain
        {
            get
            {
                UInt16 g1 = BitConverter.ToUInt16(param, 56);
                return g1;
            }
            set
            {
                param[56] = (byte)(value & 0xff);
                param[57] = (byte)((value>>8) & 0xff);
            }
        }
        [CategoryAttribute(CATEGORY5)]
        [DisplayName("掉灯延时")]
        [PropertyOrder(21)]
        public UInt16 JPDropDelay
        {
            get
            {
                return BitConverter.ToUInt16(param, 58);
            }
            set
            {


                param[58] = (byte)(value & 0xff);
                param[59] = (byte)((value >> 8) & 0xff);
            }
        }


        #endregion

        #region TVM430
        [CategoryAttribute(CATEGORY6)]
        [DisplayName("解码允许")]
        [PropertyOrder(22)]
        public bool TVM430Allow
        {
            get
            {
                uint val = BitConverter.ToUInt16(param, 60);
                return (val == 1) ? true : false;
            }
            set
            {

                uint val = (uint)(value ? 1 : 0);
                param[60] = (byte)(val & 0xff);
                param[61] = (byte)((val >> 8) & 0xff);
            }
        }

        [CategoryAttribute(CATEGORY6)]
        [DisplayName("通道增益")]
        [DescriptionAttribute("4个载波通道的增益")]
        [PropertyOrder(23)]
        public string TVM430Gain
        {
            get
            {
                uint g1 = BitConverter.ToUInt16(param, 62);
                uint g2 = BitConverter.ToUInt16(param, 64);
                uint g3 = BitConverter.ToUInt16(param, 66);
                uint g4 = BitConverter.ToUInt16(param, 68);
                return g1 + "," + g2 + "," + g3 + "," + g4;
            }
            set
            {
                if (string.IsNullOrEmpty(value)) return;

                string[] g = value.Split(new char[] { ',' });
                if (g.Length >= 4)
                {

                    UInt16 g1 = 0;
                    UInt16 g2 = 0;
                    UInt16 g3 = 0;
                    UInt16 g4 = 0;

                    if (UInt16.TryParse(g[0], out g1) && UInt16.TryParse(g[1], out g2) && UInt16.TryParse(g[2], out g3) && UInt16.TryParse(g[3], out g4))
                    {
                        param[62] = (byte)(g1 & 0xff);
                        param[63] = (byte)((g1 >> 8) & 0xff);
                        param[64] = (byte)(g2 & 0xff);
                        param[65] = (byte)((g2 >> 8) & 0xff);
                        param[66] = (byte)(g3 & 0xff);
                        param[67] = (byte)((g3 >> 8) & 0xff);
                        param[68] = (byte)(g4 & 0xff);
                        param[69] = (byte)((g4 >> 8) & 0xff);
                    }


                }
            }
        }
        [CategoryAttribute(CATEGORY6)]
        [DisplayName("掉灯延时")]
        [PropertyOrder(24)]
        public UInt16 TVM430DropDelay
        {
            get
            {
                return BitConverter.ToUInt16(param, 70);
            }
            set
            {


                param[70] = (byte)(value & 0xff);
                param[71] = (byte)((value >> 8) & 0xff);
            }
        }


        #endregion

        #region 传感器特征码

        [CategoryAttribute(CATEGORY7)]
        [DisplayName("频率")]
        [DescriptionAttribute("单位:0.1HZ")]
        [PropertyOrder(25)]
        public UInt16 SensoirFreq
        {
            get
            {
                UInt16 freq = BitConverter.ToUInt16(param, 72);
                return freq;
            }
            set
            {
                param[72] = (byte)(value & 0xff);
                param[73] = (byte)((value>>8) & 0xff);
            }
        }
        [CategoryAttribute(CATEGORY7)]
        [DisplayName("幅度条件")]
        [DescriptionAttribute("单位:毫伏")]
        [PropertyOrder(26)]
        public UInt16 SensorAmpl
        {
            get
            {
                return BitConverter.ToUInt16(param, 74);
            }
            set
            {


                param[74] = (byte)(value & 0xff);
                param[75] = (byte)((value >> 8) & 0xff);
            }
        }

        [CategoryAttribute(CATEGORY7)]
        [DisplayName("延时条件")]
        [DescriptionAttribute("单位:毫秒")]
        [PropertyOrder(27)]
        public UInt16 SensorDelay
        {
            get
            {
                return BitConverter.ToUInt16(param, 76);
            }
            set
            {


                param[76] = (byte)(value & 0xff);
                param[77] = (byte)((value >> 8) & 0xff);
            }
        }
        #endregion
    }



    public class PropertySorter : ExpandableObjectConverter
    {
        #region Methods
        public override bool GetPropertiesSupported(ITypeDescriptorContext context)
        {
            return true;
        }

        public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
        {
            //
            // This override returns a list of properties in order
            //
            PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(value, attributes);
            ArrayList orderedProperties = new ArrayList();
            foreach (PropertyDescriptor pd in pdc)
            {
                Attribute attribute = pd.Attributes[typeof(PropertyOrderAttribute)];
                if (attribute != null)
                {
                    //
                    // If the attribute is found, then create an pair object to hold it
                    //
                    PropertyOrderAttribute poa = (PropertyOrderAttribute)attribute;
                    orderedProperties.Add(new PropertyOrderPair(pd.Name, poa.Order));
                }
                else
                {
                    //
                    // If no order attribute is specifed then given it an order of 0
                    //
                    orderedProperties.Add(new PropertyOrderPair(pd.Name, 0));
                }
            }
            //
            // Perform the actual order using the value PropertyOrderPair classes
            // implementation of IComparable to sort
            //
            orderedProperties.Sort();
            //
            // Build a string list of the ordered names
            //
            ArrayList propertyNames = new ArrayList();
            foreach (PropertyOrderPair pop in orderedProperties)
            {
                propertyNames.Add(pop.Name);
            }
            //
            // Pass in the ordered list for the PropertyDescriptorCollection to sort by
            //
            return pdc.Sort((string[])propertyNames.ToArray(typeof(string)));
        }
        #endregion
    }

    #region Helper Class - PropertyOrderAttribute
    [AttributeUsage(AttributeTargets.Property)]
    public class PropertyOrderAttribute : Attribute
    {
        //
        // Simple attribute to allow the order of a property to be specified
        //
        private int _order;
        public PropertyOrderAttribute(int order)
        {
            _order = order;
        }

        public int Order
        {
            get
            {
                return _order;
            }
        }
    }
    #endregion

    #region Helper Class - PropertyOrderPair
    public class PropertyOrderPair : IComparable
    {
        private int _order;
        private string _name;
        public string Name
        {
            get
            {
                return _name;
            }
        }

        public PropertyOrderPair(string name, int order)
        {
            _order = order;
            _name = name;
        }

        public int CompareTo(object obj)
        {
            //
            // Sort the pair objects by ordering by order value
            // Equal values get the same rank
            //
            int otherOrder = ((PropertyOrderPair)obj)._order;
            if (otherOrder == _order)
            {
                //
                // If order not specified, sort by name
                //
                string otherName = ((PropertyOrderPair)obj)._name;
                return string.Compare(_name, otherName);
            }
            else if (otherOrder > _order)
            {
                return -1;
            }
            return 1;
        }
    }
    #endregion


}
